home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / reve / events.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  15.9 KB  |  523 lines

  1. /*LINTLIBRARY*/
  2.  
  3. /*  @(#)events.c 1.18 91/11/13
  4.  *
  5.  *  Procedures for handling various events in reve.
  6.  *
  7.  *  Copyright (C) 1990, 1991 - Rich Burridge & Yves Gallot.
  8.  *  All rights reserved.
  9.  *
  10.  *  Permission is granted to copy this source, for redistribution
  11.  *  in source form only, provided the news headers in "substantially
  12.  *  unaltered format" are retained, the introductory messages are not
  13.  *  removed, and no monies are exchanged.
  14.  *
  15.  *  Permission is also granted to copy this source, without the
  16.  *  news headers, for the purposes of making an executable copy by
  17.  *  means of compilation, provided that such copy will not be used
  18.  *  for the purposes of competition in any othello tournaments, without
  19.  *  prior permission from the authors.
  20.  *
  21.  *  No responsibility is taken for any errors on inaccuracies inherent
  22.  *  either to the comments or the code of this program, but if reported
  23.  *  (see README file), then an attempt will be made to fix them.
  24.  */
  25.  
  26. #include "reve.h"
  27. #include "color.h"
  28. #include "extern.h"
  29.  
  30.  
  31. void
  32. check_button_down(item)
  33. enum panel_type item ;
  34. {
  35.   int n ;
  36.  
  37.   n = (int) item ;
  38.   if (items[n].x == -1) return ;
  39.   if (items[n].wtype != curwin) return ;
  40.   if (tinput && (n == (int) SUGGEST_BUT || n == (int) PRINT_BUT ||
  41.                  n == (int) STOP_BUT    || n == (int) UNDO_BUT))
  42.     return ;
  43.   if ((curx >  items[n].x) && (curx < (items[n].x + items[n].width)) &&
  44.       (cury >  items[n].y) && (cury < (items[n].y + items[n].height)))
  45.     {
  46.       down = nextc ;
  47.       itemno = n ;
  48.       but_inverted = itemno ;
  49.       draw_button(W_PANEL, (enum panel_type) itemno, C_ITEMS, BUT_INVERT) ;
  50.     }
  51. }
  52.  
  53.  
  54. void
  55. check_choice_down(item)
  56. enum panel_type item ;
  57. {
  58.   int n ;
  59.  
  60.   n = (int) item ;
  61.   if (items[n].wtype != curwin) return ;
  62.   if ((curx >  items[n].x) && (curx < (items[n].x + items[n].width)) &&
  63.       (cury >  items[n].y) && (cury < (items[n].y + items[n].height)))
  64.     {
  65.       down = nextc ;
  66.       itemno = n ;
  67.     }
  68. }
  69.  
  70.  
  71. void
  72. check_cycle_down(item)
  73. enum panel_type item ;
  74. {
  75.   int ix, n ;
  76.  
  77.   n = (int) item ;
  78.   if (items[n].wtype != curwin) return ;
  79.   ix = items[n].x + 40 ;
  80.        if ((curx > ix) && (curx < (ix + (CWIDTH / 2))) &&
  81.            (cury > items[n].y) && (cury < (items[n].y + CHEIGHT)) &&
  82.             nextc != RIGHT_DOWN)
  83.     {
  84.       direction = INCREMENT ;
  85.       down = nextc ;
  86.       itemno = n ;
  87.       draw_cycle(curwin, (enum panel_type) n, C_ITEMS, CY_LINVERT) ;
  88.     }
  89.   else if ((curx > ix) && (curx < (ix + CWIDTH)) &&
  90.            (cury > items[n].y) && (cury < (items[n].y + CHEIGHT)) &&
  91.             nextc != RIGHT_DOWN)
  92.     {
  93.       direction = DECREMENT ;
  94.       down = nextc ;
  95.       itemno = n ;
  96.       draw_cycle(curwin, (enum panel_type) n, C_ITEMS, CY_RINVERT) ;
  97.     }
  98. }
  99.  
  100.  
  101. void
  102. check_item_down()
  103. {
  104.   int n ;
  105.  
  106.   for (n = 0; n < MAXITEMS; n++)
  107.     switch (items[n].type)
  108.       {
  109.         case P_BUTTON  : check_button_down((enum panel_type) n) ;
  110.                          break ;
  111.         case P_CHOICE  : check_choice_down((enum panel_type) n) ;
  112.                          break ;
  113.         case P_CYCLE   : check_cycle_down((enum panel_type) n) ;
  114.                          break ;
  115.         case P_MESSAGE : break ;      /* Do nothing. */
  116.         case P_TOGGLE  : check_toggle_down((enum panel_type) n) ;
  117.       }
  118. }
  119.  
  120.  
  121. void
  122. check_item_up()
  123. {
  124.   if ((nextc == LEFT_UP   && down == LEFT_DOWN)   ||
  125.       (nextc == MIDDLE_UP && down == MIDDLE_DOWN) ||
  126.       (nextc == RIGHT_UP  && down == RIGHT_DOWN))
  127.     {
  128.       if (items[itemno].type == P_BUTTON && but_inverted == -1) return ;
  129.       handle_item(items[itemno].value) ;
  130.  
  131.       switch (items[itemno].type)
  132.         {
  133.           case P_BUTTON : if (items[itemno].x != -1)
  134.                             draw_button(items[itemno].wtype,
  135.                                         (enum panel_type) itemno,
  136.                                         W_COLOR(C_ITEMS), BUT_NORMAL) ;
  137.                           break ;
  138.           case P_CHOICE : draw_choice(items[itemno].wtype,
  139.                                       (enum panel_type) itemno,
  140.                                       W_COLOR(C_PANEL)) ;
  141.                           break ;
  142.           case P_CYCLE  : draw_cycle(items[itemno].wtype,
  143.                                      (enum panel_type) itemno,
  144.                                      W_COLOR(C_ITEMS), CY_NORMAL) ;
  145.                           break ;
  146.           case P_TOGGLE : draw_toggle(items[itemno].wtype,
  147.                                       (enum panel_type) itemno,
  148.                                       W_COLOR(C_PANEL)) ;
  149.         }
  150.     } 
  151. }
  152.  
  153.  
  154. void
  155. check_toggle_down(item)
  156. enum panel_type item ;
  157. {
  158.   int n ;
  159.  
  160.   n = (int) item ;
  161.   if (items[n].wtype != curwin) return ;
  162.   if ((curx >  items[n].x) && (curx < (items[n].x + items[n].width)) &&
  163.       (cury >  items[n].y) && (cury < (items[n].y + items[n].height)))
  164.     {
  165.       down = nextc ;
  166.       itemno = n ;
  167.     }
  168. }
  169.  
  170.  
  171. void
  172. do_action()
  173. {
  174.   int cx, cy, thismove ;
  175.  
  176.   switch (nextc)
  177.     {
  178.       case MOUSE_MOVING : if (ANIMATION)
  179.                             draw_piece(next_player, piece_x, piece_y, RINV) ;
  180.                           piece_x = curx - pieceXrad ;
  181.                           piece_y = cury - pieceYrad ;
  182.  
  183.                           cx = (piece_x + pieceXrad - bborder) / cell_width ;
  184.                           cy = (piece_y + pieceYrad - bborder) / cell_height ;
  185.  
  186.                           if (cx >= 0 && cy >= 0 && cx < 8 && cy < 8)
  187.                             {
  188.                               thismove = cy * BOARD_SIZE + cx ;
  189.  
  190.                               if (thismove != last_outline)
  191.                                 draw_outline(last_outline, IS_OFF) ;
  192.                               last_outline = thismove ;
  193.                               draw_outline(last_outline, IS_ON) ;
  194.                             }
  195.  
  196.                           if (ANIMATION)
  197.                             draw_piece(next_player, piece_x, piece_y, RINV) ;
  198.                           break ;
  199.                           
  200.       case ENTER_WINDOW : 
  201.       case EXIT_WINDOW  : set_cursor(CANVASCUR) ;
  202.                           draw_outline(last_outline, IS_OFF) ;
  203.                           last_outline = -1 ;
  204.                           if (ANIMATION)
  205.                             draw_piece(next_player, piece_x, piece_y, RINV) ;
  206.                           cmode = (enum cantype) ((int) cmode - 1) ;
  207.                           break ;
  208.                           
  209.       case LEFT_DOWN    : 
  210.       case LEFT_UP      :
  211.       case MIDDLE_DOWN  :
  212.       case MIDDLE_UP    :
  213.       case RIGHT_DOWN   :
  214.       case RIGHT_UP     : set_cursor(CANVASCUR) ;
  215.                           do_selection(nextc) ;
  216.     }                 
  217. }
  218.  
  219.  
  220. void
  221. do_key(item, ch)
  222. int item, ch ;
  223. {
  224.   int color, maxw, val ;
  225.  
  226.   color = W_COLOR(C_PANEL) ;
  227.   if (!validkey)
  228.     {
  229.       validkey = cur_ch ;
  230.       switch (item)
  231.         {
  232.           case 'C' : message(PANEL_MES, items[(int) COMP_CHOICE].label) ;
  233.                      break ;
  234.           case 'D' : message(PANEL_MES, items[(int) DIFF_CHOICE].label) ;
  235.                      break ;
  236.           case 'O' : message(PANEL_MES, "Option?") ;
  237.         }
  238.     }
  239.   else
  240.     {
  241.       val = -1 ;
  242.       switch (item)
  243.         {
  244.           case 'C' : itemno = (int) COMP_CHOICE ;
  245.                      switch (ch)
  246.                        {
  247.                          case 'a' :                  /* All (both). */
  248.                          case 'A' : val = CP_BOTH ;
  249.                                     break ;
  250.                          case 'b' :                  /* Black. */
  251.                          case 'B' : val = CP_BLACK ;
  252.                                     break ;
  253.                          case 'n' :                  /* Neither. */
  254.                          case 'N' : val = CP_NEITHER ;
  255.                                     break ;
  256.                          case 'w' :                  /* White. */
  257.                          case 'W' : val = CP_WHITE ;
  258.                                     break ;
  259.                          default  : return ;
  260.                        }
  261.                      maxw = items[itemno].width / items[itemno].nopts ;
  262.                      curx = items[itemno].x + (maxw * val) ;
  263.                      items[itemno].value = val ;
  264.                      break ;
  265.  
  266.           case 'D' : itemno = (int) DIFF_CHOICE ;
  267.                      if (ch >= '1' && ch <= '9') val = ch - '1' ;
  268.                      maxw = items[itemno].width / items[itemno].nopts ;
  269.                      curx = items[itemno].x + (maxw * val) ;
  270.                      items[itemno].value = val ;
  271.                      break ;
  272.  
  273.           case 'O' : switch (ch)
  274.                        {
  275.                          case 'a' :
  276.                          case 'A' : itemno = (int) OPT_ANIM ;
  277.                                     break ;
  278.                          case 'b' :
  279.                          case 'B' : itemno = (int) OPT_BEST ;
  280.                                     break ;
  281.                          case 'c' :
  282.                          case 'C' : itemno = (int) OPT_CLK ;
  283.                                     break ;
  284.                          case 'l' :
  285.                          case 'L' : itemno = (int) OPT_LAST ;
  286.                                     break ;
  287.                          case 'e' :
  288.                          case 'E' : itemno = (int) OPT_EVAL ;
  289.                                     break ;
  290.                          case 'm' :
  291.                          case 'M' : itemno = (int) OPT_MOVE ;
  292.                                     break ;
  293.                          case 'n' :
  294.                          case 'N' : itemno = (int) OPT_NUM ;
  295.                                     break ;
  296.                          case 'f' :
  297.                          case 'F' : itemno = (int) OPT_FLIP ;
  298.                                     break ;
  299.                          default  : return ;
  300.                        }
  301.                      val = items[itemno].value ;
  302.         }
  303.       if (val != -1)
  304.         {
  305.           validkey = 0 ;
  306.           message(PANEL_MES, "") ;
  307.           items[itemno].value = item_value = val ;
  308.           direction = NONE ;
  309.           (*items[itemno].func)() ;
  310.  
  311.           switch (item)
  312.             {
  313.               case 'C' : draw_choice(W_PROPS, (enum panel_type) itemno, color) ;
  314.                          break ;
  315.               case 'D' : draw_choice(W_PROPS, (enum panel_type) itemno, color) ;
  316.                          break ;
  317.               case 'O' : draw_toggle(W_PROPS, (enum panel_type) itemno, color) ;
  318.             }
  319.         }
  320.     }
  321. }
  322.  
  323.  
  324. void
  325. do_key_move(n1, n2)
  326. int n1, n2 ;
  327. {
  328.   move = (n2 - '1') * BOARD_SIZE + (n1 - 'a') ;
  329.   next_player = (int) cmode - 1 ;
  330.   cmode = (enum cantype) ((int) cmode + 1) ;
  331.   update_clock(next_player, TRUE) ;
  332.   make_move() ;
  333.   reset_clock(next_player) ;
  334.   validkey = 0 ;
  335. }
  336.  
  337.  
  338. void
  339. get_xy(n, x, y)      /* Return piece coordinates given board index. */
  340. int n, *x, *y ;
  341. {
  342.   *x = (n &  7) * cell_width  + bborder + pieceXmargin ;
  343.   *y = (n >> 3) * cell_height + bborder + pieceYmargin ;
  344. }
  345.  
  346.  
  347. void
  348. handle_board_event()
  349. {
  350.   switch (cmode)
  351.     {
  352.       case WHITE_START  :
  353.       case BLACK_START  : next_player = (int) cmode - 1 ;
  354.                           if (nextc == LEFT_DOWN || nextc == MIDDLE_DOWN ||
  355.                               nextc == RIGHT_DOWN)
  356.                             {
  357.                               set_cursor(NOCURSOR) ;
  358.                               piece_x = curx - pieceXrad ;
  359.                               piece_y = cury - pieceYrad ;
  360.                               if (ANIMATION)
  361.                                 draw_piece(next_player,
  362.                                            piece_x, piece_y, RINV) ;
  363.                               cmode = (enum cantype) ((int) cmode + 1) ;
  364.                             }
  365.                           break ;
  366.       case WHITE_MOVING :
  367.       case BLACK_MOVING : do_action() ;
  368.     }
  369. }
  370.  
  371.  
  372. void
  373. handle_event()
  374. {
  375.   process_event() ;
  376.  
  377.        if (nextc == BOARD_REPAINT) paint_board() ;
  378.   else if (nextc == PANEL_REPAINT) paint_panel() ;
  379.   else if (nextc == HELP_REPAINT)  paint_help() ;
  380.   else if (nextc == PROPS_REPAINT) paint_prop_sheet() ;
  381.   else
  382.     {
  383.       if (processing == TRUE)
  384.         {
  385.           if (nextc == MOUSE_MOVING || nextc == IGNORE_EVENT ||
  386.               nextc == ENTER_WINDOW || nextc == EXIT_WINDOW) return ;
  387.           else
  388.             {
  389.               message(PANEL_MES, "It's not your turn.") ;
  390.               beep() ;
  391.             }
  392.           return ;
  393.         }
  394.  
  395.            if (nextc == KEYBOARD)      handle_key() ;
  396.       else if (nextc == EXIT_WINDOW && but_inverted != -1)
  397.         {
  398.           draw_button(W_PANEL, (enum panel_type) but_inverted,
  399.                       C_ITEMS, BUT_NORMAL) ;
  400.           but_inverted = -1 ;
  401.           down = 0 ;
  402.         }
  403.       else if (curwin == W_BOARD) handle_board_event() ;
  404.       else if (nextc == LEFT_UP || nextc == MIDDLE_UP || nextc == RIGHT_UP)
  405.         check_item_up() ;
  406.       else if (nextc == LEFT_DOWN   ||
  407.                nextc == MIDDLE_DOWN || nextc == RIGHT_DOWN)
  408.         check_item_down() ;
  409.     }
  410. }
  411.  
  412.  
  413. void
  414. handle_item(val)
  415. int val ;
  416. {
  417.   items[itemno].value = item_value = val ;
  418.   (*items[itemno].func)() ;
  419.   but_inverted = -1 ;
  420.   down = 0 ;
  421. }
  422.  
  423.  
  424. void
  425. handle_key()     /* Process the latest key that the user has pressed. */
  426. {
  427.   char str[9] ;  /* To display half move position. */
  428.   int nextc ;
  429.  
  430.   if (tinput)
  431.     {
  432.       get_filename() ;
  433.       return ;
  434.     }
  435.   if (cur_ch == ESCAPE) validkey = 0 ;
  436.   if (validkey)
  437.     {
  438.       nextc = cur_ch ;
  439.       cur_ch = validkey ;
  440.     }
  441.   switch (cur_ch)
  442.     {
  443.       case 'C'      :                                  /* Computer choice. */
  444.       case 'D'      :                                  /* Difficulty. */
  445.       case 'O'      : do_key(cur_ch, nextc) ;          /* Options. */
  446.                       break ;
  447.  
  448.       case 'H'      : do_help() ;
  449.                       break ;
  450.       case 'M'      : show_all_moves() ;               /* Button items. */
  451.                       break ;
  452.       case 'L'      : curx = 0 ;
  453.                       draw_textfield() ;
  454.                       break ;
  455.       case 'P'      : print_game() ;
  456.                       break ;
  457.       case 'n'      : new_game() ;
  458.                       break ;
  459.       case 'r'      : redo() ;
  460.                       break ;
  461.       case 'S'      : curx = BBORDER + (2*(BWIDTH+BGAP)) ;
  462.                       draw_textfield() ;
  463.                       break ;
  464.       case 's'      : suggest() ;
  465.                       break ;
  466.       case 'u'      : undo() ;
  467.                       break ;
  468.       case 'p'      : do_props() ;
  469.                       break ;
  470.  
  471.       case CTL('l') : paint_all() ;
  472.                       break ;
  473.  
  474.       case 'q'      : destroy_reve() ;
  475.                       exit(0) ;
  476.  
  477.       case '1'      :
  478.       case '2'      :
  479.       case '3'      :
  480.       case '4'      :
  481.       case '5'      :
  482.       case '6'      :
  483.       case '7'      :
  484.       case '8'      : if (!validkey)
  485.                         {
  486.                           validkey = cur_ch ;
  487.                           SPRINTF(str, "Move: %c", cur_ch) ;
  488.                           message(PANEL_MES, str) ;
  489.                         }
  490.                       else if (nextc >= 'a' && nextc <= 'h')
  491.                         {
  492.                           SPRINTF(str, "Move: %c%c", cur_ch, nextc) ;
  493.                           message(PANEL_MES, str) ;
  494.                           do_key_move(nextc, cur_ch) ;
  495.                         }
  496.                       else validkey = 0 ;
  497.                       break ;
  498.       case 'a'      :
  499.       case 'b'      :
  500.       case 'c'      :
  501.       case 'd'      :
  502.       case 'e'      :
  503.       case 'f'      :
  504.       case 'g'      :
  505.       case 'h'      : if (!validkey)
  506.                         {
  507.                           validkey = cur_ch ;
  508.                           SPRINTF(str, "Move: %c", cur_ch) ;
  509.                           message(PANEL_MES, str) ;
  510.                         }
  511.                       else if (nextc >= '1' && nextc <= '8')
  512.                         {
  513.                           SPRINTF(str, "Move: %c%c", cur_ch, nextc) ;
  514.                           message(PANEL_MES, str) ;
  515.                           do_key_move(cur_ch, nextc) ;
  516.                         }
  517.                       else validkey = 0 ;
  518.                       break ;
  519.       default       : message(PANEL_MES, "") ;
  520.                       validkey = 0 ;
  521.     }
  522. }
  523.